懒人赏析YOLO V1
懒人赏析系列
YOLO (You Only Look Once) 是第一个相对成功的One-Stage物体检测方法,在2016年被提出,以简单,高效的优势,一跃成为与RCNN系列并驾齐驱的物体检测框架,直至今日,YOLO V3依然作为物体检测的首选方案之一。下面,我们一同走进YOLO V1的世界。
0.大纲
YOLO V1的优势
YOLO V1的流程
YOLO V1的核心
YOLO V1损失函数
1.YOLO V1的优势
评估一个算法是否可用时,我们首先想到的是它的优势,YOLO V1的优势可总结为三点:
速度快(体现在很高的FPS,这也是YOLO V1主打的亮点);
误检少(体现在检测出的物体中,其实是背景类的比较少);
泛化能力强(体现在可以检测出美术画中的物体);
为了方便大家理解,下面copy一些论文中的图:
mAP和FPS的对比数据:
YOLO V1的速度和准确率在2016年时还是很“稳”的,很多重速度系统,会优先考虑YOLO V1。
FastRCNN与YOLO V1简单对比:
图中显示:在检测出的框中,Fast RCNN有更多框其实是背景,侧面反映出YOLO V1的误检率低;
YOLOV1的泛化能力指标:
在美术画中,YOLO V1也能表现良好(作者竟然不比较Faster RCNN…,巧妙)。
2.YOLO V1的流程
欣赏一下YOLO V1的运行过程,把目光移至下图(copy自论文):
这张图,诠释了YOLO V1的运行过程:
1.输入一张图,然后Resize到448 x 448;
2.然后输入到CNN中(文中叫darknet);
3.输出结果,经过后处理,包括NMS,得到结果(框和类别);
其中CNN整体的结构是由24个卷积层和2个全链接层组成,激活函数为“Leaky ReLU”,最后输出的向量维度是1470 = 7 x 7 x 30,说明最后输出了 7 x 7“组”结果,每组结果由30个数组成。网络结构如下:
这里需要注意,输入图片是448 x 448,输出是 7 x 7,Feature Stride为64(这个值蛮大的);
3.YOLO V1的核心
YOLO V1核心的思想是把图片分成Sx S个网格(grid cell),然后每个网格负责检测“一个”框和类别,再经过概率和NMS过滤,得到最终结果。
阅读原论文或者看完上面的描述,大家不禁会有下面几个疑问:
1)S是多少?
直接回答S=7,由于网格(grid cell)的数目需要跟最后特征图尺寸一一对应,最后特征图的尺寸为 7 x 7,因此网格的数目也就是 S x S = 7 x 7。
2)为什么要分成S x S个网格?
用以预测结果(框和类别)的特征图大小为 7 x 7,有49个向量(这里有点像RPN),每个向量都要去预测“框”和“类别”,训练时,我们需要为每个向量分配类别以及是否需要负责预测框,那么如何分配呢?我们需要把7x 7个点映射回原图,正好形成7 x 7个网格,然后根据每个网格跟Ground Truth之间的关系(作者设定了规则去建立联系),来做后续分配。也就是为什么分成S x S(7 x 7)个框了。
3)选择哪些网格(grid cell)去预测框?
每个网格在最后7 x 7的特征图上对应一个向量,这个30维向量用来预测结果,那么我们应该选择哪个网格来负责预测框呢?通俗一些,就是哪些网格是正例,哪些是负例(过程有点儿类似RPN,但区别蛮大),我们先看文中的一段描述:
这句话给了我们标准答案,物体的“中心”落在哪个网格中,哪个网格就负责训练这个框(类别和坐标)。这句英文大家都能看懂,但是实际呢?我们看看下面这张图:
这张图,中心点被标出来了,并且落在了“橘黄网格”中,那么它就是正例,那么“绿色网格”和“白色网格”的标签(Label)是什么呢?这里是与RPN最大不同之处了,YOLOV1中,对于一个Ground Truth,有且只有一个网格是正例,其余的就算与Ground Truth IOU很大,也是负例,所以“绿色网格”和“白色网格”Label为负,所以也就不用负责训练框坐标了(但是会负责训练其他信息)。
4)选好了网格,下一步计算x,y,w,h(用来训练),它们是怎么计算的?
我们看看原文怎么说:
根据原论文我们可以确定几点,第一:x,y指的是中心点,是物体框的中心点,不是网格的中心点(当然物体的中心点必然会落在相应的网格中);第二,w,h指的是物体框的宽高;第三,x,y, w, h都在0-1之间。我们在训练的时候,损失函数(LossFunction)计算的是预测的(x‘,y’,w‘,h’)与实际值(x,y,w,h)之间的L2-Loss,预测值是通过网络,最后在30维向量中(7 x 7 x 30),实际值是怎么算的呢?
比如图片的宽高为width,height,物体的中心点为x,y,宽高为w,h,那么根据论文的描述:
x,y在Loss中的值是相对网格的偏移,是相对于网格的中心点还是左上角点的偏移呢?其实这个顾虑是多余的,因为在最后7 x 7大小的特征图上,网格仅仅是一个”点“,相对于它的偏移,我们需要把x,y也映射到7 x 7的特征图上,然后与对应的网格的位置相减,然而我们不难发现,这个过程可以简化为:
根据”选取网格 “的方法,我们知道中心点x,y在7 x 7特征图上的位置的整数部分就是对应网格的位置,因为它们在原图上距离也不超过448 / S(网格的大小),所以在7 x 7的图片上,它们的距离不超过1。
5)实际的训练过程中,需要分S x S个网格么?
根据上一个问题的答案,我们不难发现,实际的训练和预测的过程中,我们是不需要对原图划分网格的,论文中划分网格的目的主要是为了方便表达。
6)最后输出的30维向量,代表什么?
论文中说了,我们一共预测98个框(明明只有49组向量),所以30维向量中一定包含了2个框的信息,也就是两组(x, y, w, h)。由于是在Pascal VOC上训练的,所以还有20个类别信息,这样组合发现只有28个值,。。。难道大家就没有疑问,YOLO V1是如何区分背景的么?YOLO V1不仅预测了框的x, y, w, h,还预测了框的分数,用来判断是不是框,所以30维向量成分:2组( x, y, w, h, score) + 20个类别概率。
7)框的分数是怎么算的?
预测的时候,分数是直接输出的,那么训练的时候呢?是不是选中的网格分数为1,没选中的为0,答案是NO,这也是YOLO V1的巧妙之处,YOLO V1计算了一个所谓的IOU分数,IOU指的是预测的框与实际框的IOU,这样在训练的时候,我们需要实时的计算这个IOU,作为输入到Loss Function中的“目标”,与预测的IOU分数做L2-Loss,举个例子,第一次迭代,网络会输出一个预测框P1,对应的真实框为G,程序会计算P1和G的IOU,然后继续做Loss。
8)为什么每个输出有两个框,实际却只负责一个框?
其中YOLO V1有一个细节,我画图描述一下:
其中,绿色的框P1与白色的框P2是网络预测的框,而红色的框G是真实值,YOLO V1会计算P1与G的IOU1,以及P2与G的IOU2,然后比较哪个IOU大,比如IOU2更大,那么P2的信息会输入到LossFunction中,P1被忽略掉(??)并不是100%被忽略,如果IOU1小于一个阈值,会作为负例,压向0值。
4.YOLO V1的损失函数
损失函数公式如上,里面有几个值得我们借鉴的地方:
1)对于平方差,同样很小的数值,对于大框影响相对于小框的影响小一些,(同样的值,加在大框上,可能几乎没有变化,而小框的变化会很大),此时作者是如何处理的呢?
文中是把w,h都开根号了,预测的是开根号的值,这样影响会相对一致一些。
2)由于每个框只有一个网格负责,那么49个网格,预测98个框,可能只有1-2个是正例,其余的都是负例,需要取向零,这样会导致网络更好的学习负例:
文中的做法是赋予不同的权重,预测坐标的权重为5,“没有物体“的权重为0.5,权重相差10倍。
以上就是YOLO V1的主要内容了,我个人建议大家读读论文,感受思想,不用去实现,毕竟YOLO V2,V3更好。